package com.coolrui.domain.order.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.impl.StateMachineException;
import com.coolrui.common.system.ApiList;
import com.coolrui.common.utils.MockDataUtils;
import com.coolrui.domain.order.entity.OrderGoods;
import com.coolrui.domain.order.entity.UserOrder;
import com.coolrui.domain.statemachine.OrderStateMachine;
import com.coolrui.domain.statemachine.dto.OrderContext;
import com.coolrui.domain.statemachine.enums.OrderEvent;
import com.coolrui.domain.statemachine.enums.OrderPayType;
import com.coolrui.domain.statemachine.enums.OrderState;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
@Slf4j
public class UserOrderHandleService {
    @Autowired
    private UserOrderDomainService userOrderDomainService;
    @Autowired
    private MockDataUtils mockDataUtils;

    /**
     * 创建模拟订单
     * @param userId 用户ID
     * @param orderNum 订单数量
     * @return 订单列表
     */
    public List<UserOrder> createMockOrder(Long userId, Integer orderNum) {
        List<UserOrder> orderList = new ArrayList<>();
        for (int i = 0; i < orderNum; i++) {
            UserOrder order = getMockOrder(userId);
            int ret = userOrderDomainService.createOrder(order);
            if (ret > 0) {
                orderList.add(order);
            }
        }
        return orderList;
    }

    /**
     * 获取用户的模拟订单数据
     * @param userId 用户ID
     * @return 订单实体
     */
    public UserOrder getMockOrder(Long userId) {
        // 订单总金额
        BigDecimal orderPrice = BigDecimal.valueOf(0.00);
        //随机2-4个商品
        int num = mockDataUtils.getNum(2, 4);
        List<OrderGoods> goodslist = new ArrayList<>();
        for (int index = 0; index < num; index++) {
            //当前商品购买数量
            int goodsNum = mockDataUtils.getNum(1, 2);
            //当前商品单价、总价
            BigDecimal goodsPrice = new BigDecimal(String.format("%.2f", Math.random() * 3 + 2));
            BigDecimal totalPrice = NumberUtil.mul(goodsPrice, goodsNum);
            orderPrice = NumberUtil.add(orderPrice, totalPrice);
            //构造当前商品数据
            OrderGoods goods = new OrderGoods();
            goods.setGoodsName(mockDataUtils.getGoods());
            goods.setGoodsNum(goodsNum);
            goods.setGoodsPrice(String.valueOf(goodsPrice));
            goods.setTotalPrice(String.valueOf(totalPrice));

            goodslist.add(goods);
        }
        // Mock订单数据
        UserOrder order = new UserOrder();
        order.setOrderId(IdUtil.getSnowflakeNextId());
        order.setShopId(mockDataUtils.getShopId());
        order.setUserId(userId);
        order.setUserName(mockDataUtils.getName());
        order.setUserMobile(mockDataUtils.getMobile());
        order.setUserCity(mockDataUtils.getCityId());
        order.setUserAddress(mockDataUtils.getAddress());
        order.setOrderGoods(JSONUtil.toJsonStr(goodslist));
        order.setOrderPrice(orderPrice);
        return order;
    }

    /**
     * 查询订单
     * @param orderId 订单ID
     */
    public UserOrder getOrder(Long orderId) {
        return userOrderDomainService.getOrder(orderId);
    }

    /**
     * 分页查找用户订单列表-API接口格式
     * @param userId 用户ID
     * @param page 页码
     * @param pageSize 每页订单条数
     * @return 订单列表
     */
    public ApiList<UserOrder> getOrderList(Long userId, Integer page, Integer pageSize){
        return userOrderDomainService.getOrderList(userId, page, pageSize);
    }

    /**
     * 支付订单
     * @param orderId 订单ID
     */
    public UserOrder payOrder(Long orderId) {
        //查询订单信息
        UserOrder userOrder = Optional.ofNullable(userOrderDomainService.getOrder(orderId))
                .orElseThrow(() -> new RuntimeException("此订单号不存在"));
        OrderState orderState = Optional.ofNullable(OrderState.getInstance(userOrder.getOrderStatus()))
                .orElseThrow(() -> new RuntimeException("订单状态异常"));
        if (!Objects.equals(userOrder.getOrderStatus(), OrderState.INIT.getCode())) {
            throw new RuntimeException("此订单已支付，无需再次支付");
        }
        //OrderContext
        OrderContext context = new OrderContext(orderId, OrderPayType.WX);
        StateMachine<OrderState, OrderEvent, OrderContext> stateMachine = OrderStateMachine.getStateMachine();
        stateMachine.fireEvent(orderState, OrderEvent.PAY, context);
        return userOrder;
    }

    /**
     * 取消订单
     * @param orderId 订单ID
     */
    public UserOrder cancelOrder(Long orderId) {
        //查询订单信息
        UserOrder userOrder = Optional.ofNullable(userOrderDomainService.getOrder(orderId))
                .orElseThrow(() -> new RuntimeException("此订单号不存在"));
        OrderState orderState = Optional.ofNullable(OrderState.getInstance(userOrder.getOrderStatus()))
                .orElseThrow(() -> new RuntimeException("订单状态异常"));
        if (Objects.equals(userOrder.getOrderStatus(), OrderState.CANCELED.getCode())) {
            throw new RuntimeException("此订单已取消，无需再次取消");
        }

        StateMachine<OrderState, OrderEvent, OrderContext> stateMachine = OrderStateMachine.getStateMachine();
        if (!stateMachine.verify(orderState, OrderEvent.CANCEL)) {
            throw new StateMachineException("订单当前状态暂不支持取消");
        }
        //OrderContext
        OrderContext context = new OrderContext(orderId);
        stateMachine.fireEvent(orderState, OrderEvent.CANCEL, context);
        return userOrder;
    }
}